#ifndef SERVER_H
#define SERVER_H


#include "pthread.h"
#define SUCCESS 0


class Dispatcher;
class Resolver;
class Logger;
class Threads;
class WorkQueue;
class Request;
class FileSystem;

struct Message
{
public:
	Request* m_pReq;
	Message()
	{
		m_pReq = NULL;
	};
};


class Server
{

	friend	class Threads;

	pthread_t	m_ResolverThread;
	pthread_t	m_DispatcherThread;
	pthread_t	m_AuthenticationThread;
	pthread_t	m_WorkerThread[2];

	pthread_attr_t	m_ResolverAttr;
	pthread_attr_t	m_DispatcherAttr;
	pthread_attr_t	m_AuthenticationAttr;
	pthread_attr_t  m_WorkQueueAttr;

	pthread_mutex_t	m_ResolveQueueMutex;
	pthread_mutex_t m_WorkQueueMutex;

	pthread_mutex_t m_AuthMutex;
	pthread_mutex_t m_FileMapMutex;

	pthread_cond_t	m_AuthResReady;
	pthread_cond_t	m_AuthReqReady;

	//pthread_cond_t	m_WorkQueueHasValues;
	pthread_cond_t	m_ResolvQueueHasValues;

	//pthread_condattr_t	m_AuthCondAttr;

	Logger&					LOGGER;
	Logger&					ERRLOGGER;


	void	InitThreads();
	bool	LockResolveQueue();
	bool	UnLockResolveQueue();

	bool	LockWorkQueue();
	bool	UnLockWorkQueue();

	bool	LockAuth();
	bool	UnLockAuth();

	bool	LockFileMap();
	bool	UnLockFileMap();

	//bool	RecvAuthRes( Request* pReq );
	//bool	SignalAuthCond();
	//bool	WaitAuthCond();

	bool	InsertInResolveQueue( Request* );
	bool	Authenticate( Request* );
	//bool	InsertInWorkQueue( Request* );




	Message	m_ReqAuth;
	//Message m_ResAuth;

public:

	Server( Dispatcher& , Resolver& ,WorkQueue& ,FileSystem&  ,Logger& , Logger& );
	~Server();

	bool	StartServer();


	Dispatcher&	dispatcher;
	Resolver&	resolver;
	WorkQueue&	workQueue;
	FileSystem&	fileSystem;
	pthread_t	thDispatcher;
	pthread_t	thResolver;
};


#endif
